{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 1,
   "id": "7bef0e88",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "response= {\"status_code\": 200, \"request_id\": \"05555ed3-0632-94c1-a3f6-f8b434ee559e\", \"code\": \"\", \"message\": \"\", \"output\": {\"text\": null, \"finish_reason\": null, \"choices\": [{\"finish_reason\": \"function_call\", \"message\": {\"role\": \"assistant\", \"content\": \"\", \"function_call\": {\"name\": \"get_current_weather\", \"arguments\": \"{\\\"location\\\": \\\"Dalian, Liaoning\\\"}\"}}}]}, \"usage\": {\"input_tokens\": 206, \"output_tokens\": 22, \"prompt_tokens_details\": {\"cached_tokens\": 0}, \"total_tokens\": 228}}\n",
      "message= {\"role\": \"assistant\", \"content\": \"\", \"function_call\": {\"name\": \"get_current_weather\", \"arguments\": \"{\\\"location\\\": \\\"Dalian, Liaoning\\\"}\"}}\n",
      "arguments= {'location': 'Dalian, Liaoning'}\n",
      "tool_info= {'role': 'function', 'name': 'get_current_weather', 'content': '{\"location\": \"Dalian, Liaoning\", \"temperature\": 10, \"unit\": null, \"forecast\": [\"\\\\u6674\\\\u5929\", \"\\\\u5fae\\\\u98ce\"]}'}\n",
      "messages= [{'role': 'user', 'content': '大连的天气怎样'}, Message({'role': 'assistant', 'content': '', 'function_call': {'name': 'get_current_weather', 'arguments': '{\"location\": \"Dalian, Liaoning\"}'}}), {'role': 'function', 'name': 'get_current_weather', 'content': '{\"location\": \"Dalian, Liaoning\", \"temperature\": 10, \"unit\": null, \"forecast\": [\"\\\\u6674\\\\u5929\", \"\\\\u5fae\\\\u98ce\"]}'}]\n",
      "response= {\"status_code\": 200, \"request_id\": \"477d0a71-b7c1-952c-b68a-114e41bda4b6\", \"code\": \"\", \"message\": \"\", \"output\": {\"text\": null, \"finish_reason\": null, \"choices\": [{\"finish_reason\": \"stop\", \"message\": {\"role\": \"assistant\", \"content\": \"大连现在的天气是多云转微风，温度大约是10摄氏度。\"}}]}, \"usage\": {\"input_tokens\": 283, \"output_tokens\": 22, \"prompt_tokens_details\": {\"cached_tokens\": 0}, \"total_tokens\": 305}}\n",
      "最终结果: {\"role\": \"assistant\", \"content\": \"大连现在的天气是多云转微风，温度大约是10摄氏度。\"}\n"
     ]
    }
   ],
   "source": [
    "import json\n",
    "import os\n",
    "import dashscope\n",
    "from dashscope.api_entities.dashscope_response import Role\n",
    "dashscope.api_key = \"sk-你的KEY\"\n",
    "from openai import OpenAI\n",
    "\n",
    "# 编写你的函数\n",
    "def get_current_weather(location, unit=\"摄氏度\"):\n",
    "    # 获取指定地点的天气\n",
    "    temperature = -1\n",
    "    if '大连' in location or 'Dalian' in location:\n",
    "        temperature = 10\n",
    "    if location=='上海':\n",
    "        temperature = 36\n",
    "    if location=='深圳':\n",
    "        temperature = 37\n",
    "    weather_info = {\n",
    "        \"location\": location,\n",
    "        \"temperature\": temperature,\n",
    "        \"unit\": unit,\n",
    "        \"forecast\": [\"晴天\", \"微风\"],\n",
    "    }\n",
    "    return json.dumps(weather_info)\n",
    "\n",
    "# 封装模型响应函数\n",
    "def get_response(messages):\n",
    "    try:\n",
    "        response = dashscope.Generation.call(\n",
    "            model='qwen-turbo',\n",
    "            messages=messages,\n",
    "            functions=functions,\n",
    "            result_format='message'\n",
    "        )\n",
    "        return response\n",
    "    except Exception as e:\n",
    "        print(f\"API调用出错: {str(e)}\")\n",
    "        return None\n",
    "\n",
    "# 使用function call进行QA\n",
    "def run_conversation():\n",
    "    query = \"大连的天气怎样\"\n",
    "    messages=[{\"role\": \"user\", \"content\": query}]\n",
    "    \n",
    "    # 得到第一次响应\n",
    "    response = get_response(messages)\n",
    "    if not response or not response.output:\n",
    "        print(\"获取响应失败\")\n",
    "        return None\n",
    "        \n",
    "    print('response=', response)\n",
    "    \n",
    "    message = response.output.choices[0].message\n",
    "    messages.append(message)\n",
    "    print('message=', message)\n",
    "    \n",
    "    # Step 2, 判断用户是否要call function\n",
    "    if hasattr(message, 'function_call') and message.function_call:\n",
    "        function_call = message.function_call\n",
    "        tool_name = function_call['name']\n",
    "        # Step 3, 执行function call\n",
    "        arguments = json.loads(function_call['arguments'])\n",
    "        print('arguments=', arguments)\n",
    "        tool_response = get_current_weather(\n",
    "            location=arguments.get('location'),\n",
    "            unit=arguments.get('unit'),\n",
    "        )\n",
    "        tool_info = {\"role\": \"function\", \"name\": tool_name, \"content\": tool_response}\n",
    "        print('tool_info=', tool_info)\n",
    "        messages.append(tool_info)\n",
    "        print('messages=', messages)\n",
    "        \n",
    "        #Step 4, 得到第二次响应\n",
    "        response = get_response(messages)\n",
    "        if not response or not response.output:\n",
    "            print(\"获取第二次响应失败\")\n",
    "            return None\n",
    "            \n",
    "        print('response=', response)\n",
    "        message = response.output.choices[0].message\n",
    "        return message\n",
    "    return message\n",
    "\n",
    "functions = [\n",
    "    {\n",
    "      'name': 'get_current_weather',\n",
    "      'description': 'Get the current weather in a given location.',\n",
    "      'parameters': {\n",
    "            'type': 'object',\n",
    "            'properties': {\n",
    "                'location': {\n",
    "                    'type': 'string',\n",
    "                    'description': 'The city and state, e.g. San Francisco, CA'\n",
    "                },\n",
    "                'unit': {'type': 'string', 'enum': ['celsius', 'fahrenheit']}\n",
    "            },\n",
    "        'required': ['location']\n",
    "      }\n",
    "    }\n",
    "]\n",
    "\n",
    "if __name__ == \"__main__\":\n",
    "    result = run_conversation()\n",
    "    if result:\n",
    "        print(\"最终结果:\", result)\n",
    "    else:\n",
    "        print(\"对话执行失败\")"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.11.6"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
